﻿#if !WINDOWS_PHONE
using System;
using Microsoft.Xna.Framework.Storage;
using System.IO;

namespace JGLib.Settings
{
    /// <summary>The class used to represent a file that uses the Xna storage system. Binary.BinaryFile and Records.RecordFile inherit from this class.</summary>
    public abstract class XnaFile
    {
        /// <summary>Gets the storage device used to save and load file.</summary>
        public static StorageDevice Storage { get; private set; }
        /// <summary>Gets or sets the title of the application that is using the file system.</summary>
        public static string TitleName { get; set; }

        /// <summary>Initializes the file system with a storage device and an application title.</summary>
        /// <param name="device">A storage device.</param>
        /// <param name="titleName">The name of the application.</param>
        public static void Initialize(StorageDevice storage, string titleName)
        {
            XnaFile.Storage = storage;
            XnaFile.TitleName = titleName;
        }

        /// <summary>Gets or sets the path to this file.</summary>
        public string FilePath { get; set; }

        /// <summary>Initializes a new instance of an XnaFile with a file path.</summary>
        /// <param name="filePath">The path to this file.</param>
        public XnaFile(string filePath)
        {
            this.FilePath = filePath;
            this.Refresh();
        }

        /// <summary>Writes default text if this file cannot be found, and then reads text.</summary>
        public void Refresh()
        {
            using (StorageContainer container = JGLib.Settings.Storage.GetStorageContainer(XnaFile.Storage, XnaFile.TitleName))
            {
                if (!container.FileExists(this.FilePath))
                {
                    Console.WriteLine("The file could not be found."
                        + "Creating new file and writing default text. (JGLib.Settings.XnaFile.Refresh()).");
                    using (Stream writer = container.CreateFile(this.FilePath))
                        this.WriteDefaultText(writer);
                }
                using (Stream reader = container.OpenFile(this.FilePath, FileMode.Open, FileAccess.Read))
                    this.ReadText(reader);
            }
        }
        /// <summary>Writes default text if this file cannot be found; otherwise, writes text.</summary>
        public void Flush()
        {
            using (StorageContainer container = JGLib.Settings.Storage.GetStorageContainer(XnaFile.Storage, XnaFile.TitleName))
            {
                bool fileExists;
                using (Stream writer = ((fileExists = container.FileExists(this.FilePath)) ? 
                    container.OpenFile(this.FilePath, FileMode.Open, FileAccess.Write)
                    : container.CreateFile(this.FilePath)))
                {
                    if (!fileExists)
                    {
                        Console.WriteLine("The file could not be found."
                            + "Creating new file and writing default text. (JGLib.Settings.XnaFile.Flush()).");
                        this.WriteDefaultText(writer);
                    }
                    else
                        this.WriteText(writer);
                }
            }
            Refresh();
        }

        /// <summary>Writes default text to this file.</summary>
        /// <param name="stream">The stream with which to write text.</param>
        protected abstract void WriteDefaultText(Stream stream);
        /// <summary>Writes normal text to this file.</summary>
        /// <param name="stream">:The stream with which to write text.</param>
        protected abstract void WriteText(Stream stream);
        /// <summary>:Processes text from this file.</summary>
        /// <param name="stream">The stream with which to read text.</param>
        protected abstract void ReadText(Stream stream);
    }
}
#endif